<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>单例模式-自定义弹出层</title>
    <style>
        .tip {
            width: 600px;
            height: 300px;
            border: solid 1px #333;
            position: fixed;
            /*固定*/
            top: 0;
            left: 0;
            right: 0;
            bottom: 0;
            margin: auto;
            background-color: #FFF;

        }

        div.tip>.top {
            height: 20px;
            background-color: skyblue;
            padding: 20 0px;
        }

        div.tip>.top>span {
            height: 15px;
            width: 15px;
            text-align: center;
            vertical-align: middle;
            display: inline-block;
            border: solid 1px;
        }

        div.tip>.content {
            height: 200px;
            text-align: center;
        }

        div.tip>.btns {
            position: absolute;
            bottom: 0px;
            right: 0px;
            width: 100%;
            height: 40px;
            background-color: skyblue;
            display: flex;
            justify-content: flex-end;
            align-items: center;
        }

        .btns button {
            width: 80px;
            height: 80%;
        }
    </style>
</head>

<body>
    <!-- <div class="tip">
        <div class="top">标题 <span style="float: right;">X</span></div>
        <div class="content">提示内容</div>
        <div class="btns">
            <button>确认</button>
            <button>取消</button>
        </div>
    </div> -->
    <script>
        /*自定义弹出层，
        1.写一个构造函数
        2.改造单例模式
        =>书写闭包 
        =>单例核心代码
        =>把类放在闭包里面
        */
        //单例模式-功能
        const Tip = (function (params) {
            //功能类
            class Tip {
                constructor() {
                    this.ele = document.createElement("div")
                    this.ele.className = 'tip'
                    document.body.appendChild(this.ele)
                    //添加一个属性，是回调函数
                    this.callback = function () { }
                    this.bindEvent()
                }
                //1.填充内容,添加HTML模板字符串
                setcontent(text) {
                    this.ele.innerHTML = ` <div class="top">标题 <span class='close' style="float: right;">X</span></div>
        <div class="content">${text}</div>
        <div class="btns">
            <button class="ok">确认</button>
            <button class="cancel">取消</button>
        </div>`
                    this.ele.style.display = 'block'
                }
                //2.添加事件，必须使用事件委托
                bindEvent() {
                    this.ele.addEventListener('click', e => {
                        e = e || window.event
                        const target = e.target || e.srcElement
                        if (target.className === 'close') {
                            this.ele.style.display = 'none'
                        }
                        if (target.className === 'cancel') {
                            this.ele.style.display = 'none'
                            console.log(false);
                            this.callback(false)
                        }
                        if (target.className === 'ok') {
                            this.ele.style.display = 'none'
                            console.log(true);
                            this.callback(true)
                        }
                    })
                }
                //3.设置回调函数
                //3.调整样式
                setStyle(val) {
                    this.ele.querySelector('.top').style.backgroundColor = val

                }
            }
            //单例核心代码
            let instance = null
            return function single(options = {}, callparam) {
                console.log(options);
                //z这里的形参，接受传递进来的参数
                if (!instance) instance = new Tip()
                //保证每一次实例化的时候，都执行 setcontent函数
                //代码能来到，instance一定是实例，所以：
                instance.setcontent(options.txt || '你好世界（默认）')
                //每次都要设置样式
                instance.setStyle(options.bg || 'skyblue')
                //每次都把你穿进来的回调函数赋值给实例的callback成员

                instance.callback = callparam || function () { }//为了避免不传值，我们写一个空的函数
                return instance
            }
        })()
        // const run = new Tip()
        //const run1 = new Tip()//如果再new一次，页面会多出一个相同的节点，导致页面重复，不可取
        // run.setcontent('你好')

        //可以写 new Tip(),也可以写Tip()，都是一样的
        Tip({
            txt: '你好，李焕英！',
            bg: 'red'
        }, function a(res) {
            console.log('打印结果', res)
        })

        //1. 此时执行的是single函数
        //2. 当我们把回调函数作为参数callparam传进去之后，就可以在single()函数内部进行调用了，
        //3. 我们可以给这个callparam传参，它本身是函数，
        //   所以callparam(实际参数)),Tip('hello',function a(形式参数){console.log(形式参数)})

    </script>
</body>

</html>